/**
 * 
 */
package com.geekteam.geometrychess.extension;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

import com.geekteam.geometrychess.board.GameBoard;
import com.geekteam.geometrychess.database.DataAccessor;
import com.geekteam.geometrychess.handler.event.DisconnectEventHandler;
import com.geekteam.geometrychess.handler.event.JoinRoomEventHandler;
import com.geekteam.geometrychess.handler.event.JoinZoneEventHandler;
import com.geekteam.geometrychess.handler.event.LeaveRoomEventHandler;
import com.geekteam.geometrychess.handler.event.LoginEventHandler;
import com.geekteam.geometrychess.handler.request.JoinRoomRequestHandler;
import com.geekteam.geometrychess.room.entity.Player;
import com.geekteam.geometrychess.utils.Code;
import com.geekteam.geometrychess.utils.Commands;
import com.geekteam.geometrychess.utils.Message;
import com.smartfoxserver.v2.api.CreateRoomSettings;
import com.smartfoxserver.v2.core.SFSEventType;
import com.smartfoxserver.v2.entities.Room;
import com.smartfoxserver.v2.entities.User;
import com.smartfoxserver.v2.entities.data.ISFSObject;
import com.smartfoxserver.v2.entities.data.SFSObject;
import com.smartfoxserver.v2.exceptions.SFSCreateRoomException;
import com.smartfoxserver.v2.extensions.SFSExtension;

/**
 * @author MtRol
 *
 */
public class ChessExtension extends SFSExtension{

	public ConcurrentHashMap<Integer, GameBoard> mMapGameBoad;
	
	private ArrayList<Player> mRankMoney;
	private ArrayList<Player> mRankExp;
	
	private DataAccessor mDataAccessor;
	
	private String driverClass = "com.mysql.jdbc.Driver";
	
	@Override
	public void init() {
		// init variable
		mMapGameBoad = new ConcurrentHashMap<Integer, GameBoard>();
		mRankExp = new ArrayList<Player>();
		mRankMoney = new ArrayList<Player>();
		mDataAccessor = DataAccessor.getInstance();
		
		//create room before play game
		createRoom();
		
		//add event handler
		this.addEventHandler(SFSEventType.USER_LOGIN, LoginEventHandler.class);
		this.addEventHandler(SFSEventType.USER_JOIN_ZONE, JoinZoneEventHandler.class);
		this.addEventHandler(SFSEventType.USER_JOIN_ROOM, JoinRoomEventHandler.class);
		this.addEventHandler(SFSEventType.USER_LEAVE_ROOM, LeaveRoomEventHandler.class);
		this.addEventHandler(SFSEventType.USER_DISCONNECT, DisconnectEventHandler.class);
		
		//add request handler
		addRequestHandler(Commands.JOIN_ROOM, JoinRoomRequestHandler.class);
		
		
		// init driver for connect database
		try {
			Class.forName(driverClass).newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		
		//be sure all variable clear before play game
		reloadExtension();
	}

	@Override
	public void destroy() {
		super.destroy();
		
		removeEventHandler(SFSEventType.USER_LOGIN);
		removeEventHandler(SFSEventType.USER_JOIN_ZONE);
		removeEventHandler(SFSEventType.USER_JOIN_ROOM);
		removeEventHandler(SFSEventType.USER_LEAVE_ROOM);
		removeEventHandler(SFSEventType.USER_DISCONNECT);
		
		removeRequestHandler(Commands.JOIN_ROOM);
	}
	
	private void createRoom(){
		ArrayList<String> listGroup = (ArrayList<String>) getParentZone().getDefaultGroups();
		for (String group : listGroup) {
			CreateRoomSettings createLobby = new CreateRoomSettings();
			createLobby.setGame(false);
			createLobby.setDynamic(false);
			createLobby.setGroupId(group);
			StringBuilder sbLobby = new StringBuilder();
			sbLobby.append("Gr").append(group.substring(1, group.length()));
			createLobby.setName(sbLobby.toString());
			try {
				getParentZone().createRoom(createLobby, null);
			} catch (SFSCreateRoomException e) {
			}
			for (int i = 0; i < 100; i++) {
				CreateRoomSettings createBoard = new CreateRoomSettings();
				createBoard.setGame(true);
				createBoard.setDynamic(false);
				createBoard.setGroupId(group);
				createBoard.setMaxUsers(1000);
				StringBuilder sb = new StringBuilder();
				sb.append(group).append("b").append(i + 1);
				createBoard.setName(sb.toString());
				try {
					getParentZone().createRoom(createBoard, null);
				} catch (SFSCreateRoomException e) {
				}
			}
		}
	}
	
	private void reloadExtension(){
		ArrayList<String> listGroup = (ArrayList<String>) getParentZone().getDefaultGroups();
		for (String group : listGroup) {
			ArrayList<Room> rooms = (ArrayList<Room>) getParentZone().getRoomListFromGroup(group);
			if (rooms.size() > 0)
				for (Room room : rooms) {
					ArrayList<User> users = (ArrayList<User>) room.getUserList();
					if (users.size() > 0)
						for (User us : users) {
							String msg = Message.RELOAD_CLIENT_UPDATE_VERSION;
							sendPrivateError(Code.RELOAD_CLIENT_CODE, msg, us.getId());
							getApi().leaveRoom(us, us.getLastJoinedRoom());
						}
				}
		}
		
		mMapGameBoad.clear();
		mRankExp.clear();
		mRankMoney.clear();
	}
	
	public void sendPrivateError(int code, String msg, int uId) {
		ArrayList<User> arr = new ArrayList<User>();
		try {
			arr.add(sfsApi.getUserById(uId));
			sendPublicError(code, msg, uId, arr);
		} catch (Exception e) {
			return;
		}
	}
	
	public void sendPublicError(int code, String msg, int userId,
			List<User> players) {
		ISFSObject ob = new SFSObject();
		ob.putUtfString("msg", msg);
		ob.putInt("code", code);
		ob.putInt("userId", userId);
		send(Commands.ERROR_RS, ob, players);
	}
}
